
from djcontrol import *

from Tkinter import *
import djcontrolutil

# todo: test PIL loading .jpg, other image types

class DjImage(DjControl):
	"""
	Image widget, based on Tkinter Label.
	
	Properties:
	
	*image* - Set image. Must be in GIF,PGM,or PPM format (unless PIL is installed). Can be filepath, or a string of base64 GIF data like 'base64:M0NTueYQ=='. (If you want a caption, use a button and set the icon property, and set the borderstyle as desired.)
	*width* - Set width of control, in pixels. If set to 0, width is based on contents (the default behavior).
	*height* - Set height of control, in pixels. If set to 0, width is based on contents (the default behavior).
	
	*bgcolor* - Background color of the image. (Transparency should work as expected). RGB triplet, such as (255,0,0) for pure red.
	*color* - Foreground color of the image. RGB triplet.
	
	*borderwidth* - An integer, width of border in pixels.
	*borderstyle* - Border style. One of 'sunken','raised','groove','ridge','flat'. Default is 'sunken'.
	*anchor* - Set where in the button the text (or image) should be located. Use one of n, ne, e, se, s, sw, w, nw, or center. Default is center.
	
	"""
	
	# Note that only names beginning with '_', or the special case basecontrol, should be used.
	_autoProperties = None
	_image = None
	basecontrol = 0
	
	def __init__(self, parent, **options):
		parent = djcontrolutil.getbasecontrol(parent)
		self.basecontrol = Label(parent)
		self._autoProperties = { 
		# Property name,  Tkinter property name, SET wrapper, GET wrapper
		'bgcolor': ('background',djcontrolutil.colorToString,djcontrolutil.stringToColor),
		'color': ('foreground',djcontrolutil.colorToString,djcontrolutil.stringToColor),
		'width': ('width',None,None),
		'height': ('height',None,None),
			
		'borderwidth': ('borderwidth',None,None),
		'alignment': ('justify',djcontrolutil.stringToJustify,djcontrolutil.justifyToString),
		'borderstyle': ('relief', djcontrolutil.stringToRelief,djcontrolutil.reliefToString),
		'anchor': ('anchor',djcontrolutil.stringToAnchor,djcontrolutil.anchorToString),
		}
		self.set_many(**options)
	
	
	def clear(self):
		"""Clear image."""
		self.basecontrol.config(image=None)
		self._image = None
		self.basecontrol.update_idletasks()
	
	
	_customProperties = ('image')
	def _lookupCustomProperties(self, bSet, strAttribute, value=None):
		if strAttribute=='image':
			if bSet:
				havePIL = True
				try:
					import Image, ImageTk
				except:
					havePIL = False
				
				# Note that we keep self._image as a member variable so it does not go out of scope.
				if isinstance(value, PhotoImage):
					# Value is apparently already a photoimage
					self._image = value
				elif havePIL and isinstance(value, ImageTk.PhotoImage):
					self._image = value
				#~ elif havePIL and isinstance(value, Image.Image):
					#~ self._image = ImageTk.PhotoImage(value)
				else:
					if value.startswith('base64:'):
						value = value[len('base64:'):]
						# value should be base64 encoded GIF data.
						self._image = PhotoImage(format='gif', data=value)
						
					elif value.endswith('.gif') or value.endswith('.GIF') or value.endswith('.pgm') or value.endswith('.PGM') or value.endswith('.ppm') or value.endswith('.PPM'):
						self._image = PhotoImage(file=value)
					else:
						# Not a standard image format. try to use PIL
						if not havePIL:
							raise RuntimeError, 'Image format not supported. Install the PIL library to support more formats.'
						pilImage = Image.open(value)
						self._image = ImageTk.PhotoImage(pilImage)

				
				self.basecontrol.config(image = self._image)
				self.basecontrol.update_idletasks()
			else:
				return self.basecontrol['image']
			
